﻿
using System;
using FacebookXmpp.Parse;

namespace FacebookXmpp.Stanzas
{
	internal abstract class Stanza
	{
        protected string NextResponse;
		protected StanzaStream Stream;

		internal Expectation ResponseExpectation = Expectation.High;
		internal virtual StanzaListenCriteria ListenFor { get { return new StanzaListenCriteria();} }
		
		internal void SetStream( StanzaStream stanzaStream )
		{
			Stream = stanzaStream;
		}

        public virtual string MessageToService()
		{
			if (Stream == null)
				throw new Exception( GetType().Name + " stanza has not beed added to the StanzaCollection.");

			string temp = NextResponse;
			NextResponse = string.Empty;
			return temp;
		}

        public abstract void ProcessResponse(MessageData recieved);
		
		private static long _counter;
		protected static string NextId
		{
			get { return (++_counter).ToString(); }
		}
	}

	internal enum Expectation { High = 2, Low = 1, None = 0 }
	
	internal class StanzaListenCriteria
	{
		public string Name;
		public string Query;
		public bool AllowOpen;
		public int ResponseTimeMilliseconds;

		public const int DefaultResponseTimeMilliseconds = 500;

		public StanzaListenCriteria( ) : this( string.Empty, string.Empty, false ) 
		{ }

		public StanzaListenCriteria( string name ) : this( name, string.Empty, false )
		{ }

		public StanzaListenCriteria( string name, int responseTimeMilliseconds ) : this( name, string.Empty, false, responseTimeMilliseconds )
		{ }

		public StanzaListenCriteria(string name, string query): this(name,query, false)
		{ }

		public StanzaListenCriteria( string name, bool allowOpen ): this( name, string.Empty, allowOpen )
		{ }

		public StanzaListenCriteria(string name, string query, bool allowOpen) : this(name,query,allowOpen, DefaultResponseTimeMilliseconds)
		{ }

		public StanzaListenCriteria(string name, string query, bool allowOpen, int responseTimeMilliseconds)
		{
			Name = name;
			Query = query;
			AllowOpen = allowOpen;
			ResponseTimeMilliseconds = responseTimeMilliseconds;
		}

		public bool Match( MessageData compare)
		{
			if (compare.IsOpen && !AllowOpen)
				return false;

			if (Name == string.Empty)
				return true;

			if (compare.Name != Name)
				return false;

			if (Query == string.Empty)
				return true;

			if (compare.Path( Query ) == null)
				return false;

			return true;
		}
	}

}
